package geektime.concurrent.part2.blockingqueuedemo;

import java.util.concurrent.LinkedBlockingQueue;

/**
 * 使用BlockingQueue模拟生产者和消费者模式
 * 生产者生成随机数和钻石（一个特定的数字），消费者消费生产者生产的数字，一旦消费到钻石数字则退出
 */
public class BlockingQueueUsage {

    public static void main(String[] args) throws InterruptedException {
        int maxCount = 10;
        int nProducers = 3; // 生产者数量
        int nConsumers = Runtime.getRuntime().availableProcessors(); // 消费者数量等于当前系统的核数
        int diamondNumber = Integer.MAX_VALUE; // 模拟的钻石数字
        int diamondPerProducer = nConsumers / nProducers; // 每个生产者生产钻石的数量
        int mod = nConsumers % nProducers; // 需要用于兜底的钻石
        LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(maxCount);

        // 创建并开启生产者的线程
        for (int i = 0; i < nProducers; i++) {
            new Thread(new NumberProducer(queue, diamondPerProducer, diamondNumber)).start();
        }

        // 创建并开始消费者的线程
        for (int i = 0; i < nConsumers; i++) {
            new Thread(new NumberConsumer(queue, diamondNumber)).start();
        }

        // 可能上面的生产者生产的钻石不够，所以这里多生产一些
        new Thread(new NumberProducer(queue, diamondPerProducer + mod, diamondNumber)).start();

    }
}
